Student Instructions | Week 5 | Topics: Exhaustive approximation, epsilon, float precision
Oregon State University | ENGR 103 | Dr. Cheng Li
Predict and then verify:
Type and run this code:
x = 0.1 + 0.1 + 0.1
print(x)
print(x == 0.3)
print(abs(x - 0.3) < 1e-10)Why does x == 0.3 return False? How does the third line fix it?
Type and run each snippet.
Type and run this code:
x = 2.0
eps = 0.01 # acceptable error
step = eps ** 2 # step must be << eps
ans = 0.0
count = 0
while abs(ans**2 - x) >= eps and ans <= x:
ans += step
count += 1
if abs(ans**2 - x) < eps:
print(f'โ{x} โ {ans:.6f} (true: {x**0.5:.6f})')
print(f'Steps taken: {count:,}')
print(f'Error: {abs(ans - x**0.5):.6f}')
else:
print('Failed to find answer')Try x=9.0, eps=0.001. How many steps? How does step count change?
We want to find x where xยฒ โ 5x = target using exhaustive search, then compare to the analytical formula. Type and run this code:
# Find x where x^2 - 5x = target by exhaustive search
target = 6.0
eps = 0.005
x = 0.0
best_x = x
best_diff = abs(x**2 - 5*x - target)
while x <= 20.0:
diff = abs(x**2 - 5*x - target)
if diff < best_diff:
best_diff = diff
best_x = x
x += 0.001
# Analytical positive root: x = (5 + sqrt(25 + 4*target)) / 2
x_exact = (5 + (25 + 4*target)**0.5) / 2
print(f'Numerical x = {best_x:.4f}')
print(f'Analytical x = {x_exact:.4f}')
print(f'Error: {abs(best_x - x_exact):.5f}')Try target = 14. Does the numerical answer still match the analytical one?
Type and run this code:
print('=== Float Precision ===')
for base in [0.1, 0.2, 0.3]:
print(f'{base} ร 10 = {base * 10:.20f}')
# Approximations of ฯ and tolerance check
approx_pi = [3.142, 3.139, 3.141, 3.145, 3.137]
true_pi = 3.14159
eps_pi = 0.003
print('\n=== Pi Approximation Check ===')
for val in approx_pi:
ok = abs(val - true_pi) <= eps_pi
print(f'ฯโ{val:.3f} diff={abs(val - true_pi):.5f} {"PASS" if ok else "FAIL"}')Change eps_pi to 0.001. Which approximations fail now?
Work in pairs. The parabola y = xยฒ โ 6x + 5 has roots at x = 1 and x = 5, and a minimum of y = โ4 at x = 3. Use exhaustive approximation to find x where y equals a given target value. No functions needed โ compute y directly inside your loops.
Type and run this code to verify the parabola at key points:
# Parabola: y = x^2 - 6x + 5
# Verify known points: roots at x=1 and x=5, minimum at x=3
for x_check in [1, 3, 5]:
y_check = x_check**2 - 6*x_check + 5
print(f'x = {x_check} โ y = {y_check:.3f}')Run the verification. Do x=1 and x=5 give y=0? Does x=3 give y=โ4?
Use the starter code below. For each target_y in the list, a while loop searches
x in [0, 10] with step 0.01 and tracks the x where |y - target_y| is smallest.
targets = [-4.0, -3.0, 0.0, 3.0]
eps = 0.05
print(f'{"Target y":>10} | {"x found":>10} | {"y at x":>10} | {"Error":>8}')
print('-' * 46)
for target_y in targets:
best_x = 0.0
best_diff = float('inf')
i = 0
while i <= 1000: # 0.0 to 10.0 in steps of 0.01
x = i * 0.01 # compute x fresh โ avoids accumulated FP drift
y = x**2 - 6*x + 5
diff = abs(y - target_y)
if diff < best_diff:
best_diff = diff
best_x = x
i += 1
y_found = best_x**2 - 6*best_x + 5
print(f'{target_y:>10.1f} | {best_x:>10.4f} | {y_found:>10.4f} | {best_diff:>8.5f}')
# Extension: What happens if target_y = -5.0?
# (Hint: the minimum of this parabola is y = -4)Use exhaustive approximation to find x where xยณ = target โ the cube root of target. No math module needed: just use ** inside a while loop.
Type and run this code:
target = 50.0
eps = 0.001
step = 0.001
ans = 0.0
count = 0
while ans <= target:
if abs(ans**3 - target) < eps:
break
ans += step
count += 1
if abs(ans**3 - target) < eps:
print(f'Cube root of {target} โ {ans:.4f}')
print(f'Python says: {target**(1/3):.4f}')
print(f'Error: {abs(ans - target**(1/3)):.6f}')
print(f'Steps: {count:,}')
else:
print('Failed to find cube root')Try target = 8 and target = 125. Then change step to 0.01 โ how does accuracy change? Why?
Show TA your Part 2 table (4 target y values โ x values found). Discuss: how would you make this faster? (Preview: bisection search next week!)